/*
 * @Author: your name
 * @Date: 2021-09-10 09:20:05
 * @LastEditTime: 2021-09-30 13:41:29
 * @LastEditors: Please set LastEditors
 * @Description: 666
 * @FilePath: \gitee-kubife\biaozhu_20210910\js\index.js
 */
(function() {
    /* 画布... */
    function BZ_Canvas(opt) {
        var opt = opt || {};
        this.opt = $.extend({
            id: "",
            imageSrc: ""
        }, opt);
        // --- 画布宽度(默认屏幕宽)
        this.full_screen_width = opt.ww || window.innerWidth;
        // --- 画布高度(默认屏幕高)
        this.full_screen_height = opt.wh || window.innerHeight;
        // --- 要绘制的图片DOM
        this.image = null;
        // --- konva的image
        this.konva_image = null;
        // --- konva_image的拖拽
        //this.ki_dragable = false;
        // --- konva_transform_image
        this.konva_transform_image = null;
        // --- 图片的缩放比例(默认1)
        this.image_scale = 1;
        // --- 最小缩放比例1
        this.MININUM_SCALE = 1;
        // --- 画布的X轴坐标(默认左上角0)
        this.ctx_x = 0;
        // --- 画布的Y轴坐标(默认左上角0)
        this.ctx_y = 0;
        // --- 是否拖拽平移
        this.dragging = false;
        // --- 鼠标按下时的坐标信息
        this.image_md_pos = null;
        // --- 鼠标移动时的坐标信息
        this.image_mm_pos = null;
        // --- 鼠标抬起时的坐标信息
        this.image_mu_pos = null;
        /* ------------------------------------------- */
        // --- 存Konva_layer
        this.layers = [];
        // --- stage的mousemove事件，要先执行mousedown再触发
        this.state_mousedown = false;
        /* ------------------------------------------- */
        /* ------------------------------------------- */
        // --- 
        /* ------------------------------------------- */
        this.layerW = 0;
        this.layerH = 0;
    }
    BZ_Canvas.prototype = {
        constructor: BZ_Canvas,
        // --- 初始化
        init() {
            if (!this.opt.id) {
                return console.error("需要stage_container...");
            } 
            this.container = $("#"+this.opt.id); 
            if (!this.opt.imageSrc) {
                return console.error("缺少图片链接地址...");
            }
            var _this = this;
            this.image = new Image();
            this.image.src = this.opt.imageSrc;
            return $.Deferred(function(defer){
                _this.image.onload = function(){
                    // ---
                    _this.layerW = this.width*2;
                    _this.layerH = this.height*2;
                    // --- container
                    _this.container.css({
                        width:this.width*2+"px",
                        height:this.height*2+"px"
                    });
                    // --- Konva_stage
                    _this.stage = new Konva.Stage({
                        container: _this.opt.id,
                        width: this.width*2,
                        height: this.height*2
                    });
                    console.log("---this.stage---", _this.stage);
                    // --- 添加Konva_layer
                    _this.layers.push(
                        new Konva.Layer(
                            {
                                clearBeforeDraw: true
                            }
                            /* {
                                                x:0,
                                                y:0,
                                                width: this.full_screen_width,
                                                height: this.full_screen_height
                                            } */
                        )
                    );
                    // --- Konva_layer -> Konva_stage
                    _this.stage.add(
                        _this.layers[0]
                    );
                    // --- 是否需要图片尺寸适配屏幕显示区域
                    _this.konva_image = new Konva.Image({
                        x: 0,
                        y: 0,
                        image: _this.image,
                        width: _this.image.width * 2,
                        height: _this.image.height * 2,
                        //draggable: true
                    });
                    console.log("---_this.layers[0]---",_this.layers[0]);
                    _this.layers[0].add(
                        _this.konva_image
                    );
                    // ---
                    _this.layers[0].draw();
                    // ---
                    _this.stageBindEvents();
                    defer.resolve();
                };
                _this.image.onerror = function(){
                    defer.reject();
                }
            });
            // ---
            /* this.addImage().then(
                function() {
                    // ---
                    _this.stageBindEvents();
                }
            ); */
        },
        // --- 默认添加一张图片
        addImage() {
            if (!this.opt.imageSrc) {
                return console.error("缺少图片链接地址...");
            }
            var _this = this;
            this.image = new Image();
            this.image.src = this.opt.imageSrc;
            return $.Deferred(function(defer) {
                _this.image.onload = function() {
                    // --- 
                    _this.konva_image = new Konva.Image({
                        x: _this.full_screen_width / 2 - _this.image.width * 2 / 2,
                        y: 50,
                        image: _this.image,
                        width: _this.image.width * 2,
                        height: _this.image.height * 2,
                        draggable: true
                    });
                    //console.log("---_this.konva_image---", _this.konva_image);
                    // _this.konva_image.on("dragstart",function(){
                    //     //alert("dragstart");
                    //     _this.ki_dragable = true;
                    // });
                    // _this.konva_image.on("dragend",function(){
                    //     //alert("dragend");
                    //     _this.ki_dragable = false;
                    // });
                    _this.layers[0].add(
                        _this.konva_image
                    );
                    // --- 图片设置变换
                    // _this.konva_transform_image = new Konva.Transformer({
                    //     node: _this.konva_image,
                    //     centeredScaling: true
                    // });
                    // ---
                    // _this.layers[0].add(
                    //     _this.konva_transform_image
                    // );
                    // ---
                    _this.layers[0].draw();
                    // ---
                    //console.log("---_this.layers[0]---",_this.layers[0]);
                    defer.resolve();
                };
            });
        },
        // --- Konva_stage绑定事件
        stageBindEvents() {
            var _this = this;
            // --- mousedown
            this.stage.on("mousedown", function(mdi) {
                //console.log("---stage_mousedown_info---",mdi);
                // --- 回调外部调用
                //_this.opt.stageMDCBF && _this.opt.stageMDCBF(mdi, _this);
                // --- 
                //_this.state_mousedown = true;
            });
            // --- mousemove
            this.stage.on("mousemove", _.debounce(function(mmi) {
                // --- 
                if (!_this.state_mousedown) return false;
                //console.log("---stage_mousemove_info---",mmi);
            }, 16));
            // --- mouseup
            this.stage.on("mouseup", function(mui) {
                //console.log("---mouseup_mui---",mui);
                // --- 通过mui.evt.which (1,2,3对应鼠标的左中右)
                // --- 鼠标右键点击时不执行回调
                if(mui.evt.which===3)return false;
                // --- 回调外部调用
                _this.opt.stageMUCBF && _this.opt.stageMUCBF(mui, _this);
                // ---
                _this.state_mousedown = false;
            });
            // --- contextmenu
            this.stage.on("contextmenu", function(mui) {
                //mui.evt.defaultPrevented = true;
                mui.evt.returnValue = false;
                //mui.evt.cancelBubble = false;
                // --- 回调外部调用
                _this.opt.stageCMCBF && _this.opt.stageCMCBF(mui, _this);
                return false;
            });
        }
    };
    /* 点 + 线 */
    function BZ_CirclePlusLine(opt) {
        if(!opt.parentLayer||!("add" in opt.parentLayer)){
            console.error("需要Layer");
        }
        // --- 外部stage中的Layer
        this.parentLayer = opt.parentLayer;
        // --- 点、线不分组，直接add到parentLayer
        // --- 点、线的Konva对象分组
        /* 
            二维数组
            circleArr:[
                [], // --- 存new Konva.Circle
                []
            ]
            二维数组
            circlePointsArr:[
                [], // --- 存circle的左边点，绘制line用
                []
            ]
            一维数组
            lineArr:[
                line, // --- 存 new Konva.Line
                line
            ]
        */
        // --- 存new Konva.Circle
        this.circleArr = [];
        // --- 默认
        this.circleArr.push([]);
        // --- 存circle的左边点，绘制line用
        this.circlePointsArr = [];
        // --- 默认
        this.circlePointsArr.push([]);
        // --- 存 new Konva.Line
        this.lineArr = [];
        // --- 当前绘制的点、线段
        this.ci = 0;
        // --- lineOptions(线的配置参数)
        this.lineOptions = $.extend({
            points: [/* 100,100,200,200,300,300 */],
            fill: "rgba(255,215,0,.25)",
            stroke: 'yellow',
            strokeWidth: 4,
            lineJoin: 'round',
            //tension: 1, // --- 样条曲线
            //closed: true, // --- 多段线自动闭合???
            /*
             * line segments with a length of 33px
             * with a gap of 10px
             */
            //dash: [33, 10]
        },opt.lineOpt||{});
        // --- points(绘制line线段时用line.setPoints(this.points)) 
        //this.points = [];
        // --- circleOptions(点的配置参数)
        this.circleOptions = $.extend({
            x: "",
            y: "",
            radius: 8,
            fill: 'pink',
            stroke: '#fff',
            strokeWidth: 2,
            draggable: true
        },opt.circleOpt||{});
    }
    BZ_CirclePlusLine.prototype = {
        constructor: BZ_CirclePlusLine,
        // --- 初始化group
        init(){
            
        },
        // --- 点击鼠标右键结束绘制的时候???
        setCi(){
            // --- 前一点、线已绘制
            if(this.circleArr[this.ci].length>0){
                //alert(this.ci);
                this.circleArr.push([]);
                this.circlePointsArr.push([]);
                this.ci = this.circleArr.length - 1;
            }
        },
        // ---
        // --- 创建line
        addLine(options) {
            var _this = this;
            var opt = $.extend(
                true, {},
                this.lineOptions,
                options || {}
            );
            var line = new Konva.Line(opt);
            // --- 加ci标记
            line.ci = this.ci;
            //console.log("---line---",line);
            //console.log("---this.lineGroup---",this.lineGroup);
            // ---
            line.on("mouseenter",function(evt){
                _this.ci = evt.currentTarget.ci;
                evt.currentTarget.setStrokeWidth(8);
                _this.parentLayer.draw();
            });
            // ---
            line.on("mouseout",function(evt){
                evt.currentTarget.setStrokeWidth(4);
                _this.parentLayer.draw();
            });
            // --- 点击线段添加circle
            line.on("mouseup", function(mui) {
                //console.log("---mui---", mui);
                //alert("add circle by line mouseup");
                // --- 阻止事件冒泡
                mui.cancelBubble = true;
                // --- 加一个点
                _this.addCircle({
                    //x: mui.evt.clientX,
                    //y: mui.evt.clientY
                    x: mui.evt.layerX,
                    y: mui.evt.layerY
                });
                // --- 修改this.circleGroup.children中的circle顺序
                /* console.log(
                    _this.circleGroup.children.pop()
                );*/
                // --- 新增的circle(每次add都是circleGroup.children的最后一项)
                var newAddCircle = _this.circleArr[_this.ci].pop();
                // --- 获取新排序的index
                var ri = _this.getNewCircleIndex([
                    newAddCircle.attrs.x,
                    newAddCircle.attrs.y
                ]);
                console.log("---ri---",ri);
                try {
                    _this.circleArr[_this.ci].splice(ri+1,0,newAddCircle);
                } catch (error) {
                    _this.circleArr[_this.ci].push(newAddCircle);
                }
                // --- 刷新points坐标集合
                _this.refreshPoints();
                // ---
                _this.parentLayer.draw();
            });
            // ---
            this.parentLayer.add(
                line
            );
            return line;
        },
        // --- 刷新points坐标集合
        refreshPoints(){
            if (this.circleArr[this.ci].length) {
                // --- 清空坐标点
                this.circlePointsArr[this.ci].splice(
                    0,
                    this.circlePointsArr[this.ci].length
                );
                // ---
                //console.log("---this.circleArr[this.ci]---",this.circleArr[this.ci]);
                _.each(
                    _.map(this.circleArr[this.ci], function(item) {
                        return {
                            x: item.attrs.x,
                            y: item.attrs.y
                        };
                    }),
                    function(item) {
                        this.circlePointsArr[this.ci].push(item.x);
                        this.circlePointsArr[this.ci].push(item.y);
                    },
                    this
                );
                //console.log("---this.circlePointsArr[this.ci]---",this.circlePointsArr[this.ci]);
            } 
        },
        // --- 绘制line
        setLinePoints() {
            // ---
            this.refreshPoints();
            // ---
            this.lineArr[this.ci].setPoints(
                this.circlePointsArr[this.ci]
            );
            // --- batchDraw  批量绘制
            this.parentLayer.batchDraw();
        },
        // --- 创建cricle点
        addCircle(options) {
            var _this = this;
            var opt = $.extend({},
                this.circleOptions,
                options || {}
            );
            var circle = new Konva.Circle(opt);
            // --- 加ci标记
            circle.ci = this.ci;
            // --- 
            this.parentLayer.add(
                circle
            );
            // --- 存circle
            this.circleArr[this.ci].push(
                circle
            );
            //console.log("---this.circleArr[this.ci]---",this.circleArr[this.ci]);
            // --- circle加拖拽事件
            //console.log("---circle---",circle);
            // --- 点击circle的时候
            circle.on("mouseenter",function(evt){
                console.log("---evt---",evt);
                // ---
                //evt.cancelBubble = true;
                // ---
                _this.ci = evt.currentTarget.ci;
            });
            // --- 拖动点的时候重新绘制line
            circle.on("dragmove", function() {
                // ---
                _this.setLinePoints();
            });
            // --- 拖动点结束
            circle.on("dragend", function() {

            });
            circle.on("mouseup", function(evt) {
                // --- 拖拽操作不能新增circle（不触发stage的mouseup回调方法）
                evt.cancelBubble = true;
            });
            // ---
            this.parentLayer.draw();
            //console.log("---this.parentLayer---",this.parentLayer);
        },
        // --- 点击line添加circle时，通过坐标点连线判断新增的点在circleGroup.children中的下标,调整circle的顺序
        // --- 参数circleXY:新增circle的attrs中的x,y坐标 Array  [x,y]
        getNewCircleIndex(circleXY) {
            console.log("---circleXY---",circleXY);
            //var nowCircle = [400, 243];
            //var nowCircle = [400,88];
            var points = $.extend([],this.circlePointsArr[this.ci]);
            var newPoints = [];
            while (points.length) {
                newPoints.push(
                    points.splice(0, 2)
                );
            }
            console.log("---newPoints---",newPoints);
            // --- 两点间连线
            var n1, n2;
            var ri;
            for (var i = 0; i < newPoints.length; i++) {
                n1 = i;
                n2 = n1 + 1;
                if (n2 >= newPoints.length) n2 = 0;
                console.log(n1 + "------" + newPoints[n1][0]);
                console.log(n1 + "------" + newPoints[n1][1]);
                console.log(n2 + "------" + newPoints[n2][0]);
                console.log(n2 + "------" + newPoints[n2][1]);
                // ------
                var minX1, maxX1, minY1, maxY1;
                minX1 = _.min([
                    newPoints[n1][0],
                    newPoints[n2][0]
                ]);
                maxX1 = _.max([
                    newPoints[n1][0],
                    newPoints[n2][0]
                ]);
                minY1 = _.min([
                    newPoints[n1][1],
                    newPoints[n2][1]
                ]);
                maxY1 = _.max([
                    newPoints[n1][1],
                    newPoints[n2][1]
                ]);
                /* console.log("---minX1---", minX1);
                console.log("---maxX1---", maxX1);
                console.log("---minY1---", minY1);
                console.log("---maxY1---", maxY1); */
                if (
                    circleXY[0] >= minX1 && circleXY[0] <= maxX1 &&
                    circleXY[1] >= minY1 && circleXY[1] <= maxY1
                ) {
                    ri = i;
                    // --- 不要break(有些点的坐标值相差很小...)
                    //break;
                }

                if (n2 < newPoints.length - 1) {
                    n1 = n2 + 1;
                }
            }
            return ri;
        }
    };
    /*  */
    $.when($.ready).done(function() {
        var opeType = "";
        // --- 画布...
        window.BZC = new BZ_Canvas({
            id: "konva-container",
            imageSrc: "./images/test.jpg",
            // --- stage的mouseup
            stageMUCBF(mui, BZC) {
                /* ----------------------点 + 线 操作 begin------------------------------- */
                var clc = "rgb("+~~(Math.random()*255)+","+~~(Math.random()*255)+","+~~(Math.random()*255)+")";
                switch(opeType){
                    case "dot":
                        //alert("draw dots");
                        //alert(BZC_CPL_CIRCLE.groupIndex);
                        BZC_CPL_CIRCLE.addCircle({
                            x: mui.evt.layerX,
                            y: mui.evt.layerY,
                            fill:clc
                        });
                        break;
                    case "line":
                        // --- 线(与点对应的一条)
                        if(!BZC_CPL_LINE.lineArr[BZC_CPL_LINE.ci]){
                            BZC_CPL_LINE.lineArr[BZC_CPL_LINE.ci] = BZC_CPL_LINE.addLine({
                                stroke:clc
                            });
                        }
                        // --- 绘制点
                        BZC_CPL_LINE.addCircle({
                            x: mui.evt.layerX,
                            y: mui.evt.layerY,
                            fill:clc
                        });
                        // --- 绘制线
                        BZC_CPL_LINE.setLinePoints();
                        break;
                    case "line-closed":
                        console.log("---BZC_CPL_LINE_CLOSED---",BZC_CPL_LINE_CLOSED);
                        // --- 线(与点对应的一条)
                        if(!BZC_CPL_LINE_CLOSED.lineArr[BZC_CPL_LINE_CLOSED.ci]){
                            BZC_CPL_LINE_CLOSED.lineArr[BZC_CPL_LINE_CLOSED.ci] = BZC_CPL_LINE_CLOSED.addLine({
                                stroke:clc,
                                tension:0.2,
                                closed:true
                            });
                        }
                        // --- 绘制点
                        BZC_CPL_LINE_CLOSED.addCircle({
                            x: mui.evt.layerX,
                            y: mui.evt.layerY,
                            fill:clc
                        });
                        // --- 绘制线
                        BZC_CPL_LINE_CLOSED.setLinePoints();
                        break;
                    default:
                        
                        break;
                }
                /* ----------------------点 + 线 操作 begin------------------------------- */
            },
            // --- stage的contextmenu
            stageCMCBF(mui, BZC){
                /* ----------------------点 + 线 操作 begin------------------------------- */
                switch(opeType){
                    case "dot":
                        //BZC_CPL_CIRCLE.setCi();
                        //alert(BZC_CPL_CIRCLE.groupIndex);
                        //console.log("---mui---",mui);
                        break;
                    case "line":
                        BZC_CPL_LINE.setCi();
                        break;
                    case "line-closed":
                        BZC_CPL_LINE_CLOSED.setCi();
                        break;
                    default:
                        
                        break;
                }
                /* ----------------------点 + 线 操作 begin------------------------------- */
            }
        })
        BZC.init().then(function(){
            /* ----------------------点 + 线 操作 begin------------------------------- */
            // --- 点
            window.BZC_CPL_CIRCLE = new BZ_CirclePlusLine({
                parentLayer:BZC.layers[0]
            });
            // --- 线
            window.BZC_CPL_LINE = new BZ_CirclePlusLine({
                parentLayer:BZC.layers[0]
            });
            // --- 线闭合
            window.BZC_CPL_LINE_CLOSED = new BZ_CirclePlusLine({
                parentLayer:BZC.layers[0]
            });
            /* window.BZC_CPL2 = new BZ_CirclePlusLine({
                parentLayer:BZC.layers[0]
            }); */
            /* ----------------------点 + 线 操作 end------------------------------- */
            //console.log("---BZ_Canvas---",BZC);
            /* ----------------------test start------------------------------- */
            // ---
            $("#clear-before-btn").on("click",function(){
                //alert("测试撤回...");
                console.log("---BZC.layers[0]---",BZC.layers[0]);
                //console.log("---BZC.layers[0].getClearBeforeDraw---",BZC.layers[0].getClearBeforeDraw());
                //console.log("---BZC.layers[0].clearBeforeDraw---",BZC.layers[0].clearBeforeDraw());
                //BZC.layers[0].draw();
                //BZC.layers[0].clear();
                //console.log("---BZC.layers[0].clearBeforeDraw---",typeof BZC.layers[0].clearBeforeDraw);
                console.log("---BZC.layers[0].getIntersection---",BZC.layers[0].getIntersection({x:0,y:0}));
            });
            // --- 
            $("#circle-btn").on("click",function(){
                //alert("点");
                opeType = "dot";
                console.log("---BZC_CPL_CIRCLE---",BZC_CPL_CIRCLE);
                //console.log("---getClientRect---",BZC_CPL1.circleGroup.getClientRect());
                //console.log("---getClip---",BZC_CPL1.circleGroup.getClip());
            });
            // ---
            $("#line-btn").on("click",function(){
                opeType = "line";
                //alert("多个点线不闭合");
            });
            // ---
            $("#line-closed-btn").on("click",function(){
                //alert("多个点线闭合");
                opeType = "line-closed";
            });
            /* ----------------------test end------------------------------- */
        });
    });
    /*  */
    /* test begin */
    /* test end */
})();